#include "StdAfx.h"
#include "Facade.h"
#include "../MnistDigit/Digit.h"
#include "../MnistDigit/DigitVisitor.h"
#include "../MnistDigit/Load.h"
#include "../NeuralBasic/Network.h"
#include "../NeuralBasic/SaveLoad.h"
#include "Tester.h"
#include "Trainer.h"

namespace Recognition
{
	Facade::Facade(void)
		: m_network(new NeuralBasic::Network)
		, m_tester(new Tester(*m_network.get(), m_testDigits))
		, m_trainer(new Trainer(*m_network.get(), m_trainDigits))
	{
	}

	Facade::~Facade(void)
	{
	}

	void Facade::CreateNewNetwork()
	{
		std::vector<size_t> networkSize;
		networkSize.push_back(28*28);
		networkSize.push_back(800);
		networkSize.push_back(10);

		*(m_network.get())=NeuralBasic::Network(networkSize);
	}

	bool Facade::IsNetworkValid() const
	{
		return m_network->GetInputCount()>0;
	}

	bool Facade::IsTrainSetValid() const
	{
		return !m_trainDigits.empty();
	}

	bool Facade::IsTestSetValid() const
	{
		return !m_testDigits.empty();
	}

	void Facade::LoadTrainSet(const wchar_t* directory)
	{
		m_trainDigits.clear();
		MnistDigit::DigitVisitor visitor(m_trainDigits);
		MnistDigit::LoadTrainSet(directory, visitor);
	}

	void Facade::LoadTestSet(const wchar_t* directory)
	{
		m_testDigits.clear();
		MnistDigit::DigitVisitor visitor(m_testDigits);
		std::string director;//empty current dir
		MnistDigit::LoadTestSet(directory, visitor);
	}

	void Facade::Train()
	{
		m_trainer->Start();
	}

	void Facade::StopTraining()
	{
		m_trainer->Stop();
	}

	double Facade::GetTrainError()
	{
		return m_trainer->GetError();
	}


	double Facade::Test()
	{
		return m_tester->Start();
	}

	
	void Facade::SaveNetwork(const wchar_t* fileName)
	{
		NeuralBasic::Save(*m_network, fileName);
	}

	void Facade::LoadNetwork(const wchar_t* fileName)
	{
		NeuralBasic::Load(*m_network, fileName);
	}

}